package fr.gla.hibtracker.historique.collection;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.hibernate.collection.PersistentMap;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;

public class HistoricPersistentMap extends PersistentMap {

	private static final long serialVersionUID = 5933997535182131098L;
	
	transient ThreadLocal<Map<?, ?>> snapshot = new ThreadLocal<Map<?, ?>>();
	
	public HistoricPersistentMap() {}
	
	public HistoricPersistentMap(SessionImplementor session, Map map) {
		super(session, map);
	}

	public HistoricPersistentMap(SessionImplementor session) {
		super(session);
	}
	
	@Override
	public void beginRead() {
		super.beginRead();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean endRead() {
		boolean endRead = super.endRead();
		snapshot.set(new HashMap(map));
		return endRead;
	}
	
	@Override
	public void postAction() {
		super.postAction();
		EventSource eventSource = (EventSource) getSession();
		Map<?,?> snapshotValue = snapshot.get();
		Map<?,?> newValue = (Map)getValue();
		//on historise pas si on passe de null a vide ou de vide a null
		if((snapshotValue == null || snapshotValue.isEmpty()) && (newValue == null || newValue.isEmpty())){
			snapshot.set(null);
			return;
		}
		HistoriqueCollectionHelper historiqueCollectionHelper = new HistoriqueCollectionHelper(eventSource,getRole(),getOwner(),getValue(snapshot.get()),getValue((Map)getValue()));
		historiqueCollectionHelper.historise();
		snapshot.set(null);
	}
	
	private String getValue(Map<?, ?> map){
		StringBuilder builder = new StringBuilder();
		Set<String> set = new TreeSet<String>();
		if(map != null){
			for(Entry<?,?> obj : map.entrySet()){
				set.add(obj.getKey()+" : "+obj.getValue());
			}
		}
		for(String value : set){
			builder.append(value+"\n");
		}
		if(builder.length() != 0)
			builder.delete(builder.length()-1, builder.length());
		return builder.toString();
	}
	
}
